﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using ScrumLite.Services.Contracts;
using System.Globalization;

namespace ScrumLite.Services.Tests
{
    [TestClass]
    public class LinqMeasuresServiceFixture
    {
        MockRepository mocks;

        Guid projectId = Guid.NewGuid();
        Guid idProcess = Guid.NewGuid();
        Guid idMeasure = Guid.NewGuid();
        Guid idProjectMeasure = Guid.NewGuid();

        ScrumLite.Data.Measure expectedMeasure;
        ScrumLite.Data.ProjectMeasure expectedProjectMeasure;
        System.Data.Linq.EntitySet<ScrumLite.Data.Measure> measures;
        System.Data.Linq.EntitySet<ScrumLite.Data.ProjectMeasure> projectMeasures;

        [TestInitialize]
        public void Initialize()
        {
            this.mocks = new MockRepository();
            // a measure
            expectedMeasure = new ScrumLite.Data.Measure
            {
                id = idMeasure,
                fk_process = idProcess,
                name = "measure1",
                lowTresholdValue = 5,
                highTresholdValue = 10,
                ascendentMeasure = true,
                unit = "u1"
            };

            // a project measure
            expectedProjectMeasure = new ScrumLite.Data.ProjectMeasure()
            {
                id = idProjectMeasure,
                fk_measure = expectedMeasure.id,
                fk_project = projectId,
                lastMeasure = DateTime.Now,
                value = 4
            };

            // a measure set
            measures = new System.Data.Linq.EntitySet<ScrumLite.Data.Measure>();
            measures.Add(expectedMeasure);

            // a project measure set
            projectMeasures = new System.Data.Linq.EntitySet<ScrumLite.Data.ProjectMeasure>();
            projectMeasures.Add(expectedProjectMeasure);
        }

        [TestMethod]
        public void ShouldGetMeasuresByProcessName()
        {
            ScrumLite.Data.IMeasureStore store = mocks.DynamicMock<ScrumLite.Data.IMeasureStore>();

            ScrumLite.Data.Measure[] expectedMeasures = measures.ToArray();
            ScrumLite.Data.ProjectMeasure[] expectedProjectMeasures = projectMeasures.ToArray();

            // set an expectation that will do a callback and set the argument 
            // to a local member to perform Asserts later
            Expect.Call(store.GetMeasures(null))
                .Return(expectedMeasures)
                .Callback(new Func<string, bool>(g => { return true; }));
            Expect.Call(store.GetProjectMeasures(Guid.Empty, String.Empty))
                .Return(expectedProjectMeasures)
                .Callback(new Func<Guid, string, bool>((g, e) => { return true; }));
            mocks.ReplayAll();

            LinqMeasuresService service = new LinqMeasuresService(store);

            Measure[] actual = service.GetMeasuresByProcessName(projectId, "");

            Assert.AreEqual(1, actual.Length, "Array incompleto.");
            Assert.AreEqual(expectedMeasures[0].name, actual[0].Name);
            Assert.AreEqual(expectedMeasures[0].lowTresholdValue, actual[0].LowThresholdValue);
            Assert.AreEqual(expectedMeasures[0].highTresholdValue, actual[0].HighThresholdValue);
            Assert.AreEqual(expectedMeasures[0].ascendentMeasure, actual[0].AscendantMeasure);
            Assert.AreEqual(expectedMeasures[0].unit, actual[0].Unit);
            Assert.AreEqual(expectedProjectMeasures[0].value, actual[0].Value);
            Assert.AreEqual(expectedProjectMeasures[0].lastMeasure, actual[0].LastMeasure);
            Assert.AreEqual(MeasureStatus.Bad, actual[0].Status);
        }

        [TestMethod]
        public void ShouldGetMeasureStatus()
        {
            Measure actual = new Measure()
            {
                LowThresholdValue = 5,
                HighThresholdValue = 10
            };

            actual.AscendantMeasure = true;
            actual.Value = 4;
            Assert.AreEqual(MeasureStatus.Bad, actual.Status);
            actual.Value = 10;
            Assert.AreEqual(MeasureStatus.Regular, actual.Status);
            actual.Value = 12;
            Assert.AreEqual(MeasureStatus.Good, actual.Status);

            actual.AscendantMeasure = false;
            actual.Value = 4;
            Assert.AreEqual(MeasureStatus.Good, actual.Status);
            actual.Value = 10;
            Assert.AreEqual(MeasureStatus.Regular, actual.Status);
            actual.Value = 12;
            Assert.AreEqual(MeasureStatus.Bad, actual.Status);
        }
        
    }
}
